package com.android.hw.projectmenu;

import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.os.Vibrator;
import android.util.Log;

public class VibratorBackService extends Service {
	final static String TAG="hytest/VibratorBackService";
	final static String VIBRATOR_FILE="/sys/class/timed_output/vibrator/enable";
	final static boolean LOG =true;
	final int DEFAULT_VIBRATE_PERIOD=1000;  //Millis
	final int DEFAULT_PAUSE_PERIOD=0; //Millis
	private int cyclePause=DEFAULT_PAUSE_PERIOD; //Millis
	private int cycleVibrate=DEFAULT_VIBRATE_PERIOD; //Millis
	private Handler mHandle=new Handler();
	private boolean isNoStop = false;
	private long tarTime=0; //Millis
	private Vibrator mVibtator;
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();	
		if(LOG)Log.d(TAG, "onCreate");
		mVibtator = (Vibrator) this.getSystemService(Service.VIBRATOR_SERVICE);
	}


	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		if(LOG)Log.d(TAG, "onDestroy");
		onStop();
		super.onDestroy();
	}


	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		return super.onStartCommand(intent, flags, startId);
	}


	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		if(LOG)Log.d(TAG, "onBind");
		return mBinder;
	}
	
	private Runnable vibraterRunnale = new Runnable(){

		@Override
		public void run() {
			// TODO Auto-generated method stub
			long next= 0;
			long left=tarTime-System.currentTimeMillis();
			
			doVibrate(cycleVibrate);
			next = cycleVibrate+cyclePause;  //a cycle
			
			if(isNoStop){ //always vibrate
				mHandle.postDelayed(vibraterRunnale, next);
			}else{
				
				if(left>0){
					mHandle.postDelayed(vibraterRunnale, next);
				}else{
					onStop();
				}
			}
			
		}//end run
		
	};//end runnable
	
	
	IVibratorBackService.Stub mBinder = new IVibratorBackService.Stub(){
		/**
		 * delay: time to delay
		 * time:  the duration to vibrate
		 */
		@Override
		public void vibrate(long delay,long time) throws RemoteException {
			// TODO Auto-generated method stub
			onStart(delay,time);
		}
		
		/**
		 * 
		 */
		@Override
		public void stop() throws RemoteException {
			// TODO Auto-generated method stub
			if(LOG)Log.d(TAG, "vibrate stop");
			onStop();
		}
		
		/**
		 * the mills of vibrate and pause time in a cycle
		 */
		@Override
		public void setCycle(int vibrate, int pause) throws RemoteException {
			// TODO Auto-generated method stub
			if(LOG)Log.d(TAG, "setCycle vibrate="+vibrate+" pause="+pause);
			cyclePause = pause;
			cycleVibrate=vibrate;
		}
		
		/**
		 * get the cycle
		 * data[0]:cycleVibrate mills ;data[1]:cyclePause mills
		 */
		@Override
		public int[] getCycle() throws RemoteException {
			// TODO Auto-generated method stub
			int[] data=new int[2];
			data[0] = cycleVibrate;
			data[1] = cyclePause;
			return data;
		}
		
		/* return target time */
		@Override
		public long getTime() throws RemoteException {
			// TODO Auto-generated method stub
			return tarTime;
		}

		@Override
		public boolean isNoStop() throws RemoteException {
			// TODO Auto-generated method stub
			return isNoStop;
		}
		
	};
	
	/*
	 * start to vibrate
	 */
	void onStart(long delay,long time){
		if(LOG)Log.d(TAG, "onStart delay="+delay+" time="+time);
		if(time==0){
			isNoStop = true;
			tarTime=0;
		}else{
			isNoStop = false;
			long cur=System.currentTimeMillis();
			tarTime=cur+time+delay;
		}
		
		mHandle.removeCallbacks(vibraterRunnale);
		mHandle.postDelayed(vibraterRunnale,delay);
	}

	/*
	 *stop the vibrator
	 */
	void onStop(){
		if(LOG)Log.d(TAG, "onStop");
		isNoStop = false;
		tarTime=0;
		mHandle.removeCallbacks(vibraterRunnale);
		mVibtator.cancel();
//		doVibrate(0);
	}
	
	/**
	 * 
	 * @param time to vibrate
	 */
	void doVibrate(long time){
		if(LOG)Log.d(TAG, "vibrate time="+time);
		if(time<0){
			time=0;
		}
		mVibtator.vibrate(time);
//		byte[] data = num_to_Byte(time);
//		writeVibtator(data);
	}
	
//	/**
//	 * change num to asc2 style;
//	 * @param num
//	 * @return
//	 */
//	private byte[] num_to_Byte(final long num){
//		long l;
//		if(num<0){
//			l=0;
//		}else{
//			l= num;;
//		}
//		int size = 0;
//		 
//		while(true){//calculate the size of num
//			size++;
//			l=l/10;
//			if(l==0){
//				break;
//			}
//		}
//		
//		//Log.d(TAG,"num_to_Byte size="+size);
//		
//		byte[] data = new byte[size];
//		
//		int n = size;
//
//		l= num;
//		while(true){ //put num in a array
//			n--;
//			data[n]= (byte) ((l%10)+'0');
//			l=l/10;
//			
//			if(l==0 || n<0){
//				break;
//			}
//		}
//		
//		return data;
//		
//	}
//	
//	/**
//	 * write to driver
//	 * @param data: the time;0 to stop
//	 */
//	
//	private void writeVibtator(byte[] data) {
//		if(LOG)Log.d(TAG,"writeVibtator start");
//				
//	    FileOutputStream ctrl=null;
//	    
//	    try {
//			ctrl = new FileOutputStream(VIBRATOR_FILE);
//			ctrl.write(data);
//			ctrl.close();
//			
//	    } catch (IOException e) {
//	    	e.printStackTrace();
//	    	Log.e(TAG,"writeVibtator : write failed");
//	    }
//	}


}
